<?php
/*! \brief
 * This is Simple Factory Framework class of Widget Framewok
 * And shot cut of widget pool relative object 
 * You can get all of the object of Widget Framework via this class
 *\author William Su
 */
class WF
{
    private static $instance;
    public static function getDirnameFile(){
        if(! isset(self::$instance[__FUNCTION__])){
            self::$instance[__FUNCTION__] = dirname(__FILE__);
        }
        return self::$instance[__FUNCTION__];
    }
    public static function getDocumentRoot(){
        $ret = self::getDirnameFile() . '/../..';
        return $ret;
    }
    public function getWPHome(){
        if(! isset(self::$instance[__FUNCTION__])){
            if(! defined('WP_HOME')){
                require (self::getDirnameFile() . '/../repository/widgetPool/config.php');
            }
            self::$instance[__FUNCTION__] = WP_HOME;
        }
        return self::$instance[__FUNCTION__];
    }
    /**
     * @return WF
     */
    public static function getInstance(){
        if(! isset(self::$instance[__FUNCTION__])){
           self::$instance[__FUNCTION__] = new WF();
        }
        return self::$instance[__FUNCTION__];
    }
    /**
     * This method will return objIOFactory of WidgetFramework
     * @return WFIOFactory
     */
    public static function getIOFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/common/io/IOFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFIOFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFTypeFactory
     */
    public static function getTypeFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/common/type/TypeFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFTypeFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFDbFactory
     */
    public static function getDbFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/db/DbFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFDbFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFWidgetPoolFactory
     */
    public static function getWidgetPoolFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/widgetPool/WidgetPoolFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFWidgetPoolFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFConfigFactory
     */
    public static function getConfigFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/config/ConfigFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFConfigFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFExceptionFactory
     */
    public static function getExceptionFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/common/exception/ExceptionFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFExceptionFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFCacheFactory
     */
    public static function getCacheFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/common/cache/CacheFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFCacheFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFLangFileFactory
     */
    public static function getLangFileFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/common/lang/LangFileFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFLangFileFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFLangFactory
     */
    public static function getLangFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/common/lang/LangFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFLangFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFMigrateFactory
     */
    public static function getMigrateFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/migrate/MigrateFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFMigrateFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFWidgetFactory
     */
    public static function getWidgetFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/widget/WidgetFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFWidgetFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFServerFactory
     */
    public static function getServerFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/server/ServerFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFServerFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFDomFactory
     */
    public static function getDomFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/common/dom/DomFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFDomFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFBenchmarkFactory
     */
    public static function getBenchmarkFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/common/benchmark/BenchmarkFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFBenchmarkFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFSecurityFactory
     */
    public static function getSecurityFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/common/security/SecurityFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFSecurityFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFProxyFactory
     */
    public static function getProxyFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/proxy/ProxyFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFProxyFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFSoapFactory
     */
    public static function getSoapFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/common/soap/SoapFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFSoapFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFCliFactory
     */
    public static function getCliFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/common/cli/CliFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFCliFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    /**
     * @return WFControllerFactory
     */
    public static function getControllerFactory($objFramework = null){
        $key = null !== $objFramework ? get_class($objFramework) : 'null';
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require_once self::getDirnameFile() . '/controller/ControllerFactory.php';
            $objFramework = null !== $objFramework ? $objFramework : self::getInstance();
            self::$instance[__FUNCTION__][$key] = new WFControllerFactory($objFramework);
        }
        return self::$instance[__FUNCTION__][$key];
    }
    public static function varDumpDebug(){
        $numargs = func_num_args();
        $arg_list = func_get_args();
        echo '<pre>';
        for($i = 0; $i < $numargs; $i++){
            print self::getTypeFactory()->getString()->getVarLog($arg_list[$i]);
        }
        echo '</pre>';
    }
    /**
     * @return WFLogger
     */
    public static function getLoggerClient(){
        return self::getLogger('client');
    }
    /**
     * @return WFLogger
     */
    public static function getLoggerUpgradeWF(){
        return self::getLogger('upgradeWF');
    }
    /**
     * @return WFLogger
     */
    public static function getLogger($name = null){
        if(! isset(self::$instance[__FUNCTION__][$name])){
            require_once self::getDirnameFile() . '/common/log/Logger.php';
            $file_name = null !== $name ? '_' . $name : '';
            $arrConfig = require (self::getDirnameFile() . '/../resource/common/log/configurator_php' . $file_name . '.php');
            //var_dump($arrConfig);
            $rootlogger = new WFLogger($name, self::getInstance());
            if($GLOBALS['wfconf_debug'] === 'null'){
                $rootlogger->setLevel(LoggerLevel::toLevel($arrConfig['rootLogger']['level']));
                $appender = new LoggerAppenderNull("MyAppender" . $name);
                $appender->activateOptions();
                $rootlogger->removeAllAppenders();
                $rootlogger->addAppender($appender);
            }else{
                switch($name){
                    case 'client':
                        //do nothing
                        break;
                    default:
                        $session_id = ! session_id() ? 'null' : session_id();
                        $user_id = (isset($_COOKIE['userId']) && $_COOKIE['userId']) ? $_COOKIE['userId'] : 'null';
                        LoggerMDC::put('session_id', $session_id);
                        LoggerMDC::put('user_id', $user_id);
                        break;
                }
                $rootlogger->setLevel(LoggerLevel::toLevel($arrConfig['rootLogger']['level']));
                $appender = new LoggerAppenderRollingFile("MyAppender" . $name);
                $appender->setFile($arrConfig['appenders']['default']['file'], true);
                $appender->setMaxBackupIndex($arrConfig['appenders']['default']['maxBackupIndex']);
                $appender->setMaxFileSize($arrConfig['appenders']['default']['maxFileSize']);
                $appenderlayout = new LoggerLayoutPattern();
                $pattern = $arrConfig['appenders']['default']['layout']['conversionPattern'];
                $appenderlayout->setConversionPattern($pattern);
                $appender->setLayout($appenderlayout);
                $appender->activateOptions();
                $rootlogger->removeAllAppenders();
                $rootlogger->addAppender($appender);
            }
            self::$instance[__FUNCTION__][$name] = $rootlogger;
        }
        return self::$instance[__FUNCTION__][$name];
    }
    public static function getVarLog($variable){
        $ret = self::getTypeFactory()->getString()->getVarLog($variable);
        return $ret;
    }
    public static function initCLI(&$argv, &$argc){
        self::initUnitTestCLI($argv, $argc);
        self::initExecDBUpdateFilterCLI($argv, $argc);
    }
    public static function isUnitTest(){
        $ret = defined('IS_UNITTEST') ? true : false;
        return $ret;
    }
    public static function initUnitTest(){
        if(! defined('IS_UNITTEST')){
            define('IS_UNITTEST', true);
        }
    }
    public static function initUnitTestCLI(&$argv, &$argc){
        if(isset($argv) && in_array('IS_UNITTEST', $argv)){
            self::initUnitTest();
            $key = array_search('IS_UNITTEST', $argv);
            unset($argv[$key]);
            $argc = count($argv);
        }
    }
    public static function isExecDBUpdateFilter(){
        $ret = defined('IS_EXEC_DB_UPDATE_FILTER') ? true : false;
        return $ret;
    }
    public static function initExecDBUpdateFilter(){
        if(! defined('IS_EXEC_DB_UPDATE_FILTER')){
            define('IS_EXEC_DB_UPDATE_FILTER', true);
        }
    }
    public static function initExecDBUpdateFilterCLI(&$argv, &$argc){
        if(isset($argv) && in_array('IS_execDBUpdateFilter', $argv)){
            self::initExecDBUpdateFilter();
            $key = array_search('IS_execDBUpdateFilter', $argv);
            unset($argv[$key]);
            $argc = count($argv);
        }
    }
    /**
     *\brief Description
     * This method will return object of WFDataObject
     * - $strDbName default is null
     * - if $strDbName='', for MySQL CREATE DATABASE use
     * - if $strDbName=test, use DataObject connect to test database
     * @return WFDatabaseObjectSqlite
     */
    public static function getDataObject($strDbName = null){
        $key = $strDbName; //for singleton key
        if(null !== $strDbName){
            $key = md5($strDbName);
        }
        if(! isset(self::$instance[__FUNCTION__][$key])){
            require (self::getDirnameFile() . '/../config.php');
            $strDBType = self::getInstance()->getConfigFactory()->getConfig()->getDbConfigType();
            $strDBTypeUpperCamelCase = self::getInstance()->getTypeFactory()->getString()->getUpperCamelCase($strDBType);
            require_once (self::getDirnameFile() . '/common/db/DatabaseObject' . $strDBTypeUpperCamelCase . '.php');
            if(true === self::getInstance()->isUnitTest()){
                $wfconf_dbconfig["dbname"] = "tmwf_test";
                $wfconf_dbconfig["dbfile"] = self::getDocumentRoot() . "/repository/db/sqlite/tmwf_test.db";
            }
            if(null !== $strDbName){
                $wfconf_dbconfig["dbname"] = $strDbName;
            }
            //var_dump($wfconf_dbconfig);
            $strFuncDatabaseObject = 'WFDatabaseObject' . $strDBTypeUpperCamelCase;
            self::$instance[__FUNCTION__][$key] = new $strFuncDatabaseObject($wfconf_dbconfig, self::getInstance());
        }
        $ret = self::$instance[__FUNCTION__][$key];
        return $ret;
    }
    /**
     * @return WFParameter
     */
    public static function getParameter(){
        if(! isset(self::$instance[__FUNCTION__])){
            require_once self::getDirnameFile() . '/common/config/Parameter.php';
        }
        self::$instance[__FUNCTION__] = new WFParameter(self::getInstance());
        return self::$instance[__FUNCTION__];
    }
    /**
     * @return WFCollection
     */
    public static function getCollection($valueType = null){
        if(! isset(self::$instance[__FUNCTION__])){
            require_once self::getDirnameFile() . '/common/collection/Collection.php';
        }
        self::$instance[__FUNCTION__] = new WFCollection($valueType);
        return self::$instance[__FUNCTION__];
    }
}
